package backend.majiong;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComboBuilder {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ComboBuilder css = new ComboBuilder();
        css.run();
    }

    public void run() {

        List<Pai> list = new ArrayList<Pai>();
        String input = "11112345678999";
        String pz = "";
        String sz = "";
        String mz = "";
        String zp = "";
        String[] temp = input.split("m");
        String tempStr = temp[0];
        if (temp.length > 1) {
            zp = temp[1];
        }
        temp = tempStr.split("s");
        tempStr = temp[0];
        if (temp.length > 1) {
            mz = temp[1];
        }
        temp = tempStr.split("p");
        tempStr = temp[0];
        if (temp.length > 1) {
            sz = temp[1];
        }
        pz = tempStr;
        for (int i = 0; i < pz.length(); i++) {
            list.add(new Pai(Integer.valueOf(String.valueOf(pz.charAt(i))), 1));
        }
        for (int i = 0; i < sz.length(); i++) {
            list.add(new Pai(Integer.valueOf(String.valueOf(sz.charAt(i))), 2));
        }
        for (int i = 0; i < mz.length(); i++) {
            list.add(new Pai(Integer.valueOf(String.valueOf(mz.charAt(i))), 3));
        }
        for (int i = 0; i < zp.length(); i++) {
            list.add(new Pai(Integer.valueOf(String.valueOf(zp.charAt(i))), 4));
        }
        sortPai(list);
        System.out.println(list.toString());
        List<Combo> combos = getCombo(list);
        System.out.println(combos.toString());
    }

    private List<Combo> getCombo(List<Pai> list) {
        List<Pai> setPai = new ArrayList<Pai>();
        List<Integer> nums = new ArrayList<Integer>();
        //分组按牌:个数
        for (Pai hai : list) {
            int index = setPai.indexOf(hai);
            if (index == -1) {
                nums.add(1);
                setPai.add(hai);
            } else {
                nums.set(index, nums.get(index) + 1);
            }
        }
        Combo combo = new Combo();
        Integer index = 0;
        List<Combo> comboList = new ArrayList<Combo>();
        findByDep(setPai, nums, combo, index, comboList);
        return comboList;
    }

    private void findByDep(List<Pai> list, List<Integer> nums, Combo combo, Integer index, List<Combo> comboList) {
        for (; index < nums.size(); index++) {
            if (nums.get(index) != 0) {
                break;
            }
        }
        if (index.equals(nums.size())) {
            return;
        }
        Pai nowPai = list.get(index);
        if (combo.getDuiZi() == null) {
            if (nums.get(index) > 1) {
                nums.set(index, nums.get(index) - 2);
                combo.setDuiZi(nowPai);
                if (checkPaiNumIsZero(nums)) {
                    addComboToList(combo, comboList);
                } else {
                    findByDep(list, nums, combo, index, comboList);
                }
                nums.set(index, nums.get(index) + 2);
                combo.setDuiZi(null);
            }
        }

        if (nowPai.getNextPai() != null && nowPai.getNextPai().getNextPai() != null) {
            Pai nextPai = nowPai.getNextPai();
            Pai nextNextPai = nextPai.getNextPai();
            if (list.contains(nextPai) && list.contains(nextNextPai) && nums.get(index + 1) > 0
                    && nums.get(index + 2) > 0) {
                nums.set(index, nums.get(index) - 1);
                nums.set(index + 1, nums.get(index + 1) - 1);
                nums.set(index + 2, nums.get(index + 2) - 1);
                combo.getSunZi().add(nowPai);
                if (checkPaiNumIsZero(nums)) {
                    addComboToList(combo, comboList);
                } else {
                    findByDep(list, nums, combo, index, comboList);
                }
                nums.set(index, nums.get(index) + 1);
                nums.set(index + 1, nums.get(index + 1) + 1);
                nums.set(index + 2, nums.get(index + 2) + 1);
                combo.getSunZi().remove(nowPai);
            }
        }

        if (nums.get(index) > 2) {
            nums.set(index, nums.get(index) - 3);
            combo.getKeZi().add(nowPai);
            if (checkPaiNumIsZero(nums)) {
                addComboToList(combo, comboList);
            } else {
                findByDep(list, nums, combo, index, comboList);
            }
            nums.set(index, nums.get(index) + 3);
            combo.getKeZi().remove(nowPai);
        }
    }

    private boolean checkPaiNumIsZero(List<Integer> nums) {
        Integer count = 0;
        for (Integer num : nums) {
            count += num;
        }
        if (count == 0) {
            return true;
        }
        return false;
    }

    public void addComboToList(Combo combo, List<Combo> comboList) {
        Combo inCombo = new Combo();
        inCombo.setDuiZi(combo.getDuiZi());
        inCombo.getKeZi().addAll(combo.getKeZi());
        inCombo.getSunZi().addAll(combo.getSunZi());
        comboList.add(inCombo);
    }

    public void sortPai(List<Pai> list) {
        Collections.sort(list, new Comparator<Pai>() {

            @Override
            public int compare(Pai o1, Pai o2) {
                int rs = o1.getType().compareTo(o2.getType());
                if (rs != 0)
                    return rs;
                return o1.getNum().compareTo(o2.getNum());
            }

        });
    }

}
